﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Input;
using ManagedWinapi;

namespace Milkify.Input
{
    public class HotkeyContainer : IDisposable
    {
        private IContainer mContainer = new Container();

        private Hotkey mAddTask;
        public Hotkey AddTask
        {
            get
            {
                if (mAddTask == null)
                    mAddTask = CreateHotkey("AddTaskHotkey");
                return mAddTask;
            }
        }

        private Hotkey mSearchTask;
        public Hotkey SearchTask
        {
            get
            {
                if (mSearchTask == null)
                    mSearchTask = CreateHotkey("SearchTaskHotkey");
                return mSearchTask;
            }
        }

        public void ReRegisterHotkeys()
        {
            if (mAddTask != null) RegisterHotkey(mAddTask, "AddTaskHotkey");
            if (mSearchTask != null) RegisterHotkey(mSearchTask, "SearchTaskHotkey");
        }

        private Hotkey CreateHotkey(string name)
        {
            Hotkey hotkey = new Hotkey(mContainer);
            RegisterHotkey(hotkey, name);
            return hotkey;
        }

        private void RegisterHotkey(Hotkey hotkey, string name)
        {
            var propertyValue = Properties.Settings.Default[name] as string;
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(KeyGesture));
            KeyGesture keyGesture = converter.ConvertFromInvariantString(propertyValue) as KeyGesture;
            RegisterHotkey(hotkey, keyGesture.Modifiers, keyGesture.Key);
        }

        private void RegisterHotkey(Hotkey hotkey, ModifierKeys modifierKeys, Key key)
        {
            try
            {
                hotkey.Enabled = false;
                hotkey.Alt = ((modifierKeys & ModifierKeys.Alt) == ModifierKeys.Alt);
                hotkey.Ctrl = ((modifierKeys & ModifierKeys.Control) == ModifierKeys.Control);
                hotkey.Shift = ((modifierKeys & ModifierKeys.Shift) == ModifierKeys.Shift);
                hotkey.WindowsKey = ((modifierKeys & ModifierKeys.Windows) == ModifierKeys.Windows);
                hotkey.KeyCode = WpfKeyToWinFormsKeys(key);
                hotkey.Enabled = true;
            }
            catch (HotkeyAlreadyInUseException e)
            {
                throw new Exception(string.Format("Hotkey '{0}' is already registered.", modifierKeys.ToString() + ", " + key.ToString()), e);
            }
        }

        private static System.Windows.Forms.Keys WpfKeyToWinFormsKeys(Key key)
        {
            try
            {
                return (System.Windows.Forms.Keys)Enum.Parse(typeof(System.Windows.Forms.Keys), key.ToString());
            }
            catch
            {
                return System.Windows.Forms.Keys.None;
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            mContainer.Dispose();
        }

        #endregion
    }
}
